// 响应化
function defineReactive(obj, key, val) {
  let dep = new Dep()
  Object.defineProperty(obj, key, {
    enmurable: true,
    configurable: true,
    get() {
      // 收集依赖
      if (Dep.target) {
        dep.addSub(Dep.target)
      }
      return val
    },
    set(newVal) {
      // 通知更新
      val = newVal
      dep.nofity()
    }
  })
}
// 遍历递归响应化数据
function observe(data) {
  const keys = Object.keys(data)
  for (let i = 0, l = keys.length; i < l; i++) {
    let key = keys[i]
    let val = data[key]
    if (typeof val === 'object') {
      observe(val)
    }
    defineReactive(data, key, val)
  }
}
// 收集依赖
class Dep {
  constructor() {
    this.subs = []
  }
  // 添加依赖
  addSub(sub) {
    this.subs.push(sub)
  }
  // 取消依赖
  removeSub(sub) {
    let index = this.sunbs.indexOf(sub)
    if (index > -1) {
      this.subs = this.subs.splice(index, 1)
    }
  }
  // 通知更新
  nofity() {
    this.subs.forEach(sub => {
      sub.update()
    })
  }
}
// 观察者
class Watcher {
  constructor(cb) {
    this.cb = cb
    this.get()
  }
  // 触发依赖收集
  get() {
    Dep.target = this
    this.cb()
    Dep.target = null
  }
  // 回调更新
  update() {
    this.get()
  }
}

let test = {
  user: {
    name: '张三',
    age: 18
  }
}
observe(test)

function callback() {
  console.log(test.user.name, test.user.age)
}
let watch = new Watcher(callback)
test.user.name = '李四'